package com.hzhr.iot.device.service;

import com.hzhr.iot.core.annotation.ApiImplicitInternalParams;
import com.hzhr.iot.core.constant.AccessModeEnum;
import com.hzhr.iot.core.constant.CommonOptions;
import com.hzhr.iot.core.exception.ServiceException;
import com.hzhr.iot.device.constant.DeviceOptions;
import com.hzhr.iot.device.constant.DeviceOptionsName;
import com.hzhr.iot.device.constant.DeviceOptionsTypeName;
import com.hzhr.iot.device.constant.Device_ErrorsEnum;
import com.hzhr.iot.device.dao.CollectDeviceDao;
import com.hzhr.iot.device.dao.IotDeviceDao;
import com.hzhr.iot.device.dao.helper.CollectDeviceDaoHelper;
import com.hzhr.iot.device.dao.helper.IotDeviceDaoHelper;
import com.hzhr.iot.device.entity.CollectDeviceEntity;
import com.hzhr.iot.device.entity.IotDeviceEntity;
import com.hzhr.iot.device.model.flowMeter.*;
import com.hzhr.iot.device.queryModel.custom.CollectDeviceCustomQueryModel;
import com.hzhr.iot.device.queryModel.custom.IotDeviceCustomQueryModel;
import com.hzhr.iot.device.service.base.BaseService;
import com.hzhr.iot.device.service.helper.Toll_GasUserServiceHelper;
import com.hzhr.iot.device.service.helper.User_DeptServiceHelper;
import com.hzhr.iot.toll.sdk.model.gasUser.GasUserModel;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.Date;
import java.util.Map;

@Service
public class FlowMeterService extends BaseService {
    @Autowired
    Toll_GasUserServiceHelper toll_gasUserServiceHelper;
    @Autowired
    IotDeviceDaoHelper iotDeviceDaoHelper;
    @Autowired
    CollectDeviceDaoHelper collectDeviceDaoHelper;
    @Autowired
    CollectDeviceDao collectDeviceDao;
    @Autowired
    IotDeviceDao iotDeviceDao;
    @Autowired
    User_DeptServiceHelper user_deptServiceHelper;
    @Autowired
    DeviceOptions deviceOptions;

    //region javadoc注释 : post
    /**
     * 创建流量计 <br/><br/>
     * 简介 : 物联网设备公司现场实施人员创建流量计和DTU，并将该流量计和相应的DTU及燃气用户进行关联 <br/>
     * 步骤 : <br/>
     * 1. 查询燃气用户：根据请求体“流量计模型(新增)”的“流量计代码”和“所属部门编号”查询燃气用户“燃气用户_1”， <br/>
     *  如果“燃气用户_1”不存在，抛出异常“燃气用户不存在”；(√) <br/>
     * 2. 查询DTU：根据“流量计模型(新增)”的“DTU代码”查询DTU“DTU_1”；(√) <br/>
     * 3. 查询流量计：根据“流量计模型(新增)”的“流量计代码”和“所属公司编号”查询流量计“流量计_1”；(√) <br/>
     * 4. 判断流量计和DTU的存在性：如果“DTU_1”和“流量计_1”都存在，直接返回“DTU_1”和“流量计_1”的编号， <br/>
     *  如果“DTU_1”存在且“流量计_1”不存在，抛出异常“DTU代码已存在”， <br/>
     *  如果“流量计_1”存在且“DTU_1”不存在，抛出异常“流量计代码已存在”；(√) <br/>
     * 5. 创建DTU：根据“流量计模型(新增)”的信息在登录用户所在的物联网设备公司下创建DTU“DTU_2”；(√) <br/>
     * 6. 创建流量计：根据“流量计模型(新增)”的信息以及需要关联“DTU_2”和“燃气用户_1”来创建流量计“流量计_2”；(√) <br/>
     * 8. 返回信息：根据“流量计_2”和“DTU_2”生成“流量计响应模型(新增)”并返回；(√) <br/>
     * @param header <br/>
     * _token : <br/>&nbsp&nbsp&nbsp&nbsp 说明 : 令牌;<br/>&nbsp&nbsp&nbsp&nbsp 是否必填 : true;<br/>&nbsp&nbsp&nbsp&nbsp 数据类型 : string;<br/>
     * _hzhr-user-id : <br/>&nbsp&nbsp&nbsp&nbsp 说明 : 用户编号;<br/>&nbsp&nbsp&nbsp&nbsp 是否必填 : true;<br/>&nbsp&nbsp&nbsp&nbsp 数据类型 : int;<br/>
     * _hzhr-user-code : <br/>&nbsp&nbsp&nbsp&nbsp 说明 : 用户代码;<br/>&nbsp&nbsp&nbsp&nbsp 是否必填 : true;<br/>&nbsp&nbsp&nbsp&nbsp 数据类型 : string;<br/>
     * _hzhr-user-name : <br/>&nbsp&nbsp&nbsp&nbsp 说明 : 用户名;<br/>&nbsp&nbsp&nbsp&nbsp 是否必填 : true;<br/>&nbsp&nbsp&nbsp&nbsp 数据类型 : string;<br/>
     * _hzhr-company-id : <br/>&nbsp&nbsp&nbsp&nbsp 说明 : 公司编号;<br/>&nbsp&nbsp&nbsp&nbsp 是否必填 : true;<br/>&nbsp&nbsp&nbsp&nbsp 数据类型 : int;<br/>
     * _hzhr-dept-id : <br/>&nbsp&nbsp&nbsp&nbsp 说明 : 部门编号;<br/>&nbsp&nbsp&nbsp&nbsp 是否必填 : true;<br/>&nbsp&nbsp&nbsp&nbsp 数据类型 : int;<br/>
     * _hzhr-user-type : <br/>&nbsp&nbsp&nbsp&nbsp 说明 : 用户类型(关联: common_service.options.code, typeCode = 'USER_TYPE');<br/>&nbsp&nbsp&nbsp&nbsp 是否必填 : true;<br/>&nbsp&nbsp&nbsp&nbsp 数据类型 : string;<br/>
     * _hzhr-transaction-id : <br/>&nbsp&nbsp&nbsp&nbsp 说明 : 交易流水号;<br/>&nbsp&nbsp&nbsp&nbsp 是否必填 : true;<br/>&nbsp&nbsp&nbsp&nbsp 数据类型 : string;<br/>
     * _hzhr-transaction-type : <br/>&nbsp&nbsp&nbsp&nbsp 说明 : 交易类型;<br/>&nbsp&nbsp&nbsp&nbsp 是否必填 : true;<br/>&nbsp&nbsp&nbsp&nbsp 数据类型 : string;<br/>
     * _hzhr-access-mode : <br/>&nbsp&nbsp&nbsp&nbsp 说明 : 访问模式 0:一般 1:全局;<br/>&nbsp&nbsp&nbsp&nbsp 是否必填 : false;<br/>&nbsp&nbsp&nbsp&nbsp 默认值 : 0;<br/>&nbsp&nbsp&nbsp&nbsp 数据类型 : int;<br/><br/>
     * @param query <br/><br/>
     * @param body <br/><br/>
     * @throws ServiceException <br/>
     * @see FlowMeterPostModel body <br/>
     * @see FlowMeterPostResponseModel result <br/>
     */ 
    //endregion
    //region 说明 : post
    //创建流量计
    //简介 : 物联网设备公司现场实施人员创建流量计和DTU，并将该流量计和相应的DTU及燃气用户进行关联
    //步骤 :
    //1. 查询燃气用户：根据请求体“流量计模型(新增)”的“流量计代码”和“所属部门编号”查询燃气用户“燃气用户_1”，
    // 如果“燃气用户_1”不存在，抛出异常“燃气用户不存在”；(√)
    //2. 查询DTU：根据“流量计模型(新增)”的“DTU代码”查询DTU“DTU_1”；(√)
    //3. 查询流量计：根据“流量计模型(新增)”的“流量计代码”和“所属公司编号”查询流量计“流量计_1”；(√)
    //4. 判断流量计和DTU的存在性：如果“DTU_1”和“流量计_1”都存在，直接返回“DTU_1”和“流量计_1”的编号，
    // 如果“DTU_1”存在且“流量计_1”不存在，抛出异常“DTU代码已存在”，
    // 如果“流量计_1”存在且“DTU_1”不存在，抛出异常“流量计代码已存在”；(√)
    //5. 创建DTU：根据“流量计模型(新增)”的信息在登录用户所在的物联网设备公司下创建DTU“DTU_2”；(√)
    //6. 创建流量计：根据“流量计模型(新增)”的信息以及需要关联“DTU_2”和“燃气用户_1”来创建流量计“流量计_2”；(√)
    //8. 返回信息：根据“流量计_2”和“DTU_2”生成“流量计响应模型(新增)”并返回；(√)
    //endregion
    //region 参数 : post
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "令牌",required = true, dataType = "string", paramType = "header"),
    })
    @ApiImplicitInternalParams({
            @ApiImplicitParam(name = "_token", value = "令牌",required = true, dataType = "string", paramType = "header"),
            @ApiImplicitParam(name = "_hzhr-user-id", value = "用户编号",required = true, dataType = "int", paramType = "header"),
            @ApiImplicitParam(name = "_hzhr-user-code", value = "用户代码",required = true, dataType = "string", paramType = "header"),
            @ApiImplicitParam(name = "_hzhr-user-name", value = "用户名",required = true, dataType = "string", paramType = "header"),
            @ApiImplicitParam(name = "_hzhr-company-id", value = "公司编号",required = true, dataType = "int", paramType = "header"),
            @ApiImplicitParam(name = "_hzhr-dept-id", value = "部门编号",required = true, dataType = "int", paramType = "header"),
            @ApiImplicitParam(name = "_hzhr-user-type", value = "用户类型(关联: common_service.options.code, typeCode = 'USER_TYPE')",required = true, dataType = "string", paramType = "header"),
            @ApiImplicitParam(name = "_hzhr-transaction-id", value = "交易流水号",required = true, dataType = "string", paramType = "header"),
            @ApiImplicitParam(name = "_hzhr-transaction-type", value = "交易类型",required = true, dataType = "string", paramType = "header"),
            @ApiImplicitParam(name = "_hzhr-access-mode", value = "访问模式 0:一般 1:全局",defaultValue = "0", required = false, dataType = "int", paramType = "header"),
    })
    //endregion
    //region 请求 : post
    @RequestMapping(value = "/flow-meters", method = RequestMethod.POST)
    //endregion
    @Transactional(rollbackFor = Exception.class)
    public FlowMeterPostResponseModel post(Map<String, String> header, Map<String, Object> query,
                                           FlowMeterPostModel body) throws ServiceException {
        /* 查询燃气用户 */
        String gasUserCode = body.getGasUserCode();
        Integer deptId = body.getDeptId();
        GasUserModel gasUser_1 = toll_gasUserServiceHelper.getByCodeAndDeptId(initHeader(header, AccessModeEnum.GLOBAL), gasUserCode, deptId);
        if (gasUser_1 == null) {
            throw new ServiceException(Device_ErrorsEnum.COLLECTDEVICESERVICE_IMPL_ADD_FLOW_METER_201);
        }

        /* 查询DTU */
        String dtuCode = body.getDtuCode();
        String dtuCategoryCode = deviceOptions.getCode(DeviceOptionsTypeName.IOT_DEVICE_CATEGORY, DeviceOptionsName.IOT_DEVICE_CATEGORY.DTU);
        IotDeviceEntity dtu_1 = iotDeviceDaoHelper.getByCodeAndCategoryCode(dtuCode, dtuCategoryCode);

        /* 查询流量计 */
        Integer companyId = body.getCompanyId();
        String flowMeterCode = body.getFlowMeterCode();
        String flowMeterCategoryCode = deviceOptions.getCode(DeviceOptionsTypeName.COLLECT_DEVICE_CATEGORY, DeviceOptionsName.COLLECT_DEVICE_CATEGORY.FLOW_METER);
        CollectDeviceEntity flowMeter_1 = collectDeviceDaoHelper.getByCodeAndCompanyIdAndCategoryCode(flowMeterCode, companyId, flowMeterCategoryCode);

        /* 判断流量计和DTU的存在性 */
        if (dtu_1 != null && flowMeter_1 != null) {
            String transactionId = getTransactionId(header);
            FlowMeterPostResponseModel response = new FlowMeterPostResponseModel();
            response.setFlowMeterId(flowMeter_1.getId());
            response.setDtuId(dtu_1.getId());
            response.setTransactionId(transactionId);
            return response;
        }
        if (dtu_1 != null) {
            throw new ServiceException(Device_ErrorsEnum.COLLECTDEVICESERVICE_IMPL_ADD_FLOW_METER_202);
        }
        if (flowMeter_1 != null) {
            throw new ServiceException(Device_ErrorsEnum.COLLECTDEVICESERVICE_IMPL_ADD_FLOW_METER_203);
        }

        /* 创建DTU */
        Integer loginUserCompanyId = getCompanyId(header);
        String resourceCode = user_deptServiceHelper.getDeptResourceCode(initHeader(header, AccessModeEnum.GLOBAL), companyId, deptId);
        Integer loginUserId = getUserId(header);
        IotDeviceEntity dtu_2 = new IotDeviceEntity();
        dtu_2.setCode(body.getDtuCode());
        dtu_2.setDes(body.getDtuDes());
        dtu_2.setTypeId(body.getDtuTypeId());
        dtu_2.setSimNo(body.getDtuSimNo());
        dtu_2.setSimTypeCode(body.getDtuSimTypeCode());
        dtu_2.setDeptId(deptId);
        dtu_2.setCompanyId(loginUserCompanyId);
        dtu_2.setGasCompanyId(companyId);
        dtu_2.setCategoryCode(deviceOptions.getCode(DeviceOptionsTypeName.IOT_DEVICE_CATEGORY, DeviceOptionsName.IOT_DEVICE_CATEGORY.DTU));
        dtu_2.setIotPlatformDeviceId(body.getDtuCode());
        dtu_2.setIotPlatformCode(deviceOptions.getCode(DeviceOptionsTypeName.IOT_PLATFORM_TYPE, DeviceOptionsName.IOT_PLATFORM_TYPE.SELF_BUILD));
        dtu_2.setResourceCode(resourceCode);
        dtu_2.setCreateTime(new Date());
        dtu_2.setCreateUserId(loginUserId);
        dtu_2.setIsValid(CommonOptions.YES_NO.YES);
        dtu_2.setState("1");
        iotDeviceDao.insert(dtu_2);

        /* 创建流量计 */
        CollectDeviceEntity flowMeter_2 = new CollectDeviceEntity();
        flowMeter_2.setCode(body.getFlowMeterCode());
        flowMeter_2.setDes(body.getFlowMeterDes());
        flowMeter_2.setCategoryCode(deviceOptions.getCode(DeviceOptionsTypeName.COLLECT_DEVICE_CATEGORY, DeviceOptionsName.COLLECT_DEVICE_CATEGORY.FLOW_METER));
        flowMeter_2.setTypeId(body.getFlowMeterTypeId());
        flowMeter_2.setCompanyId(body.getCompanyId());
        flowMeter_2.setDeptId(deptId);
        flowMeter_2.setDeptCode(user_deptServiceHelper.getCodeById(initHeader(header, AccessModeEnum.GLOBAL), deptId));
        flowMeter_2.setGasUserId(gasUser_1.getId());
        flowMeter_2.setGasUserCode(gasUser_1.getCode());
        flowMeter_2.setGasUserName(gasUser_1.getName());
        flowMeter_2.setGasUserAddress(gasUser_1.getAddress());
        String pressureUnit = deviceOptions.getCode(DeviceOptionsTypeName.PRESSURE_UNIT, DeviceOptionsName.PRESSURE_UNIT.MPA);
        flowMeter_2.setPressureUnit(pressureUnit);//压力单位默认Mpa
        flowMeter_2.setIotDeviceId(dtu_2.getId());
        flowMeter_2.setResourceCode(resourceCode);
        flowMeter_2.setCreateTime(new Date());
        flowMeter_2.setCreateUserId(loginUserId);
        flowMeter_2.setIsValid(CommonOptions.YES_NO.YES);
        flowMeter_2.setState("1");
        collectDeviceDao.insert(flowMeter_2);

        /* 返回信息 */
        String transactionId = getTransactionId(header);
        FlowMeterPostResponseModel response = new FlowMeterPostResponseModel();
        response.setFlowMeterId(flowMeter_2.getId());
        response.setDtuId(dtu_2.getId());
        response.setTransactionId(transactionId);
        return response;
    }

    //region javadoc注释 : put
    /**
     * 修改流量计 <br/><br/>
     * 简介 : 物联网设备公司现场实施人员修改流量计和所属DTU的信息 <br/>
     * 步骤 : <br/>
     * 1. 查询流量计：根据请求体“流量计模型(修改)”的“流量计编号”查询流量计“流量计_1”， <br/>
     *  如果“流量计_1”不存在，抛出异常“流量计不存在”；(√) <br/>
     * 2. 查询DTU：根据“流量计_1”的“所属物联网设备编号”查询“DTU_1”， <br/>
     *  如果“DTU_1”不存在，抛出异常“DTU不存在”；(√) <br/>
     * 3. 验证新的流量计代码：如果“流量计模型(修改)”的“流量计代码”和“流量计_1”的“代码”不同， <br/>
     *  则验证“流量计模型(修改)”的“流量计代码”在“流量计模型(修改)”的“所属公司编号”所对应的公司下是否存在， <br/>
     *  如果存在，抛出异常“流量计代码已存在”；(√) <br/>
     * 4. 验证新的DTU代码：如果“流量计模型(修改)”的“DTU代码”和“DTU_1”的“代码”不同， <br/>
     *  则“流量计模型(修改)”的“DTU代码”是否存在，如果存在，抛出异常“DTU代码已存在”；(√) <br/>
     * 5. 验证新的所属燃气用户：如果“流量计模型(修改)”的“所属燃气用户代码”和“流量计_1”的“所属燃气用户代码”不同， <br/>
     *  则根据“流量计模型(修改)”的“所属燃气用户代码”查询“流量计模型(修改)”的“所属部门编号”所对应的部门的管辖范围内的燃气用户“燃气用户_1”， <br/>
     *  如果“燃气用户_1”不存在，抛出异常“燃气用户不存在”；(√) <br/>
     * 6. 更新流量计及DTU信息：根据“流量计模型(修改)”更新“流量计_1”和“DTU_1”的相关信息， <br/>
     *  如果“流量计模型(修改)”的“燃气用户代码”和“流量计_1”的燃气用户代码不同，则需关联“流量计_1”和“燃气用户_1”; (√) <br/>
     * 7. 返回信息：生成“流量计响应模型(修改)”并返回；(√) <br/>
     * @param header <br/>
     * _token : <br/>&nbsp&nbsp&nbsp&nbsp 说明 : 令牌;<br/>&nbsp&nbsp&nbsp&nbsp 是否必填 : true;<br/>&nbsp&nbsp&nbsp&nbsp 数据类型 : string;<br/>
     * _hzhr-user-id : <br/>&nbsp&nbsp&nbsp&nbsp 说明 : 用户编号;<br/>&nbsp&nbsp&nbsp&nbsp 是否必填 : true;<br/>&nbsp&nbsp&nbsp&nbsp 数据类型 : int;<br/>
     * _hzhr-user-code : <br/>&nbsp&nbsp&nbsp&nbsp 说明 : 用户代码;<br/>&nbsp&nbsp&nbsp&nbsp 是否必填 : true;<br/>&nbsp&nbsp&nbsp&nbsp 数据类型 : string;<br/>
     * _hzhr-user-name : <br/>&nbsp&nbsp&nbsp&nbsp 说明 : 用户名;<br/>&nbsp&nbsp&nbsp&nbsp 是否必填 : true;<br/>&nbsp&nbsp&nbsp&nbsp 数据类型 : string;<br/>
     * _hzhr-company-id : <br/>&nbsp&nbsp&nbsp&nbsp 说明 : 公司编号;<br/>&nbsp&nbsp&nbsp&nbsp 是否必填 : true;<br/>&nbsp&nbsp&nbsp&nbsp 数据类型 : int;<br/>
     * _hzhr-dept-id : <br/>&nbsp&nbsp&nbsp&nbsp 说明 : 部门编号;<br/>&nbsp&nbsp&nbsp&nbsp 是否必填 : true;<br/>&nbsp&nbsp&nbsp&nbsp 数据类型 : int;<br/>
     * _hzhr-user-type : <br/>&nbsp&nbsp&nbsp&nbsp 说明 : 用户类型(关联: common_service.options.code, typeCode = 'USER_TYPE');<br/>&nbsp&nbsp&nbsp&nbsp 是否必填 : true;<br/>&nbsp&nbsp&nbsp&nbsp 数据类型 : string;<br/>
     * _hzhr-transaction-id : <br/>&nbsp&nbsp&nbsp&nbsp 说明 : 交易流水号;<br/>&nbsp&nbsp&nbsp&nbsp 是否必填 : true;<br/>&nbsp&nbsp&nbsp&nbsp 数据类型 : string;<br/>
     * _hzhr-transaction-type : <br/>&nbsp&nbsp&nbsp&nbsp 说明 : 交易类型;<br/>&nbsp&nbsp&nbsp&nbsp 是否必填 : true;<br/>&nbsp&nbsp&nbsp&nbsp 数据类型 : string;<br/>
     * _hzhr-access-mode : <br/>&nbsp&nbsp&nbsp&nbsp 说明 : 访问模式 0:一般 1:全局;<br/>&nbsp&nbsp&nbsp&nbsp 是否必填 : false;<br/>&nbsp&nbsp&nbsp&nbsp 默认值 : 0;<br/>&nbsp&nbsp&nbsp&nbsp 数据类型 : int;<br/><br/>
     * @param query <br/><br/>
     * @param body <br/><br/>
     * @throws ServiceException <br/>
     * @see FlowMeterPutModel body <br/>
     * @see FlowMeterPutResponseModel result <br/>
     */ 
    //endregion
    //region 说明 : put
    //修改流量计
    //简介 : 物联网设备公司现场实施人员修改流量计和所属DTU的信息
    //步骤 :
    //1. 查询流量计：根据请求体“流量计模型(修改)”的“流量计编号”查询流量计“流量计_1”，
    // 如果“流量计_1”不存在，抛出异常“流量计不存在”；(√)
    //2. 查询DTU：根据“流量计_1”的“所属物联网设备编号”查询“DTU_1”，
    // 如果“DTU_1”不存在，抛出异常“DTU不存在”；(√)
    //3. 验证新的流量计代码：如果“流量计模型(修改)”的“流量计代码”和“流量计_1”的“代码”不同，
    // 则验证“流量计模型(修改)”的“流量计代码”在“流量计模型(修改)”的“所属公司编号”所对应的公司下是否存在，
    // 如果存在，抛出异常“流量计代码已存在”；(√)
    //4. 验证新的DTU代码：如果“流量计模型(修改)”的“DTU代码”和“DTU_1”的“代码”不同，
    // 则“流量计模型(修改)”的“DTU代码”是否存在，如果存在，抛出异常“DTU代码已存在”；(√)
    //5. 验证新的所属燃气用户：如果“流量计模型(修改)”的“所属燃气用户代码”和“流量计_1”的“所属燃气用户代码”不同，
    // 则根据“流量计模型(修改)”的“所属燃气用户代码”查询“流量计模型(修改)”的“所属部门编号”所对应的部门的管辖范围内的燃气用户“燃气用户_1”，
    // 如果“燃气用户_1”不存在，抛出异常“燃气用户不存在”；(√)
    //6. 更新流量计及DTU信息：根据“流量计模型(修改)”更新“流量计_1”和“DTU_1”的相关信息，
    // 如果“流量计模型(修改)”的“燃气用户代码”和“流量计_1”的燃气用户代码不同，则需关联“流量计_1”和“燃气用户_1”; (√)
    //7. 返回信息：生成“流量计响应模型(修改)”并返回；(√)
    //endregion
    //region 参数 : put
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "令牌",required = true, dataType = "string", paramType = "header"),
    })
    @ApiImplicitInternalParams({
            @ApiImplicitParam(name = "_token", value = "令牌",required = true, dataType = "string", paramType = "header"),
            @ApiImplicitParam(name = "_hzhr-user-id", value = "用户编号",required = true, dataType = "int", paramType = "header"),
            @ApiImplicitParam(name = "_hzhr-user-code", value = "用户代码",required = true, dataType = "string", paramType = "header"),
            @ApiImplicitParam(name = "_hzhr-user-name", value = "用户名",required = true, dataType = "string", paramType = "header"),
            @ApiImplicitParam(name = "_hzhr-company-id", value = "公司编号",required = true, dataType = "int", paramType = "header"),
            @ApiImplicitParam(name = "_hzhr-dept-id", value = "部门编号",required = true, dataType = "int", paramType = "header"),
            @ApiImplicitParam(name = "_hzhr-user-type", value = "用户类型(关联: common_service.options.code, typeCode = 'USER_TYPE')",required = true, dataType = "string", paramType = "header"),
            @ApiImplicitParam(name = "_hzhr-transaction-id", value = "交易流水号",required = true, dataType = "string", paramType = "header"),
            @ApiImplicitParam(name = "_hzhr-transaction-type", value = "交易类型",required = true, dataType = "string", paramType = "header"),
            @ApiImplicitParam(name = "_hzhr-access-mode", value = "访问模式 0:一般 1:全局",defaultValue = "0", required = false, dataType = "int", paramType = "header"),
    })
    //endregion
    //region 请求 : put
    @RequestMapping(value = "/flow-meters", method = RequestMethod.PUT)
    //endregion
    @Transactional(rollbackFor = Exception.class)
    public FlowMeterPutResponseModel put(Map<String, String> header, Map<String, Object> query,
                                         FlowMeterPutModel body) throws ServiceException {
        /* 查询流量计 */
        Integer flowMeterId = body.getFlowMeterId();
        if (flowMeterId == null || flowMeterId == 0) {
            throw new ServiceException(Device_ErrorsEnum.COLLECTDEVICESERVICE_IMPL_SET_FLOW_METER_201);
        }
        CollectDeviceEntity flowMeter_1 = collectDeviceDaoHelper.getById(flowMeterId);
        if (flowMeter_1 == null) {
            throw new ServiceException(Device_ErrorsEnum.COLLECTDEVICESERVICE_IMPL_SET_FLOW_METER_201);
        }

        /* 查询DTU */
        Integer flowMeterDtuId_1 = flowMeter_1.getIotDeviceId();
        if (flowMeterDtuId_1 == null || flowMeterDtuId_1 == 0) {
            throw new ServiceException(Device_ErrorsEnum.COLLECTDEVICESERVICE_IMPL_SET_FLOW_METER_202);
        }
        IotDeviceEntity dtu_1 = iotDeviceDaoHelper.getById(flowMeterDtuId_1);
        if (dtu_1 == null) {
            throw new ServiceException(Device_ErrorsEnum.COLLECTDEVICESERVICE_IMPL_SET_FLOW_METER_202);
        }

        /* 验证新的流量计代码 */
        Integer companyId = body.getCompanyId();
        String flowMeterCategoryCode = deviceOptions.getCode(DeviceOptionsTypeName.COLLECT_DEVICE_CATEGORY, DeviceOptionsName.COLLECT_DEVICE_CATEGORY.FLOW_METER);
        String flowMeterCode = body.getFlowMeterCode();
        String flowMeterCode_1 = flowMeter_1.getCode();
        if (!flowMeterCode.equals(flowMeterCode_1)) {
            int existCount = collectDeviceDaoHelper.getCountByCountAndCompanyIdAndCategoryCode(flowMeterCode, companyId, flowMeterCategoryCode);
            if (existCount > 0) {
                throw new ServiceException(Device_ErrorsEnum.COLLECTDEVICESERVICE_IMPL_SET_FLOW_METER_203);
            }
        }

        /* 验证新的DTU代码 */
        String dtuCategoryCode = deviceOptions.getCode(DeviceOptionsTypeName.IOT_DEVICE_CATEGORY, DeviceOptionsName.IOT_DEVICE_CATEGORY.DTU);
        String dtuCode = body.getDtuCode();
        String dtuCode_1 = dtu_1.getCode();
        if (!dtuCode.equals(dtuCode_1)) {
            int existCount = iotDeviceDaoHelper.getCountByCodeAndCategoryCode(dtuCode, dtuCategoryCode);
            if (existCount > 0) {
                throw new ServiceException(Device_ErrorsEnum.COLLECTDEVICESERVICE_IMPL_SET_FLOW_METER_204);
            }
        }

        /* 验证新的所属燃气用户 */
        Integer deptId = body.getDeptId();
        String gasUserCode = body.getGasUserCode();
        String flowMeterGasUserCode_1 = flowMeter_1.getGasUserCode();
        GasUserModel gasUser_1 = null;
        if (!gasUserCode.equals(flowMeterGasUserCode_1)) {
            gasUser_1 = toll_gasUserServiceHelper.getByCodeAndDeptId(initHeader(header, AccessModeEnum.GLOBAL), gasUserCode, deptId);
            if (gasUser_1 == null) {
                throw new ServiceException(Device_ErrorsEnum.COLLECTDEVICESERVICE_IMPL_SET_FLOW_METER_205);
            }
        }

        /* 更新流量计及DTU信息 */
        Integer loginUserId = getUserId(header);
        //更新流量计
        CollectDeviceCustomQueryModel collectDeviceCustomQueryModel = new CollectDeviceCustomQueryModel();
        collectDeviceCustomQueryModel.setEqual_id(flowMeter_1.getId());
        collectDeviceCustomQueryModel.setSet_code(flowMeterCode);
        collectDeviceCustomQueryModel.setSet_des(body.getFlowMeterDes());
        collectDeviceCustomQueryModel.setSet_typeId(body.getFlowMeterTypeId());
        collectDeviceCustomQueryModel.setSet_deptId(deptId);
        collectDeviceCustomQueryModel.setSet_deptCode(user_deptServiceHelper.getCodeById(initHeader(header, AccessModeEnum.GLOBAL), deptId));
        collectDeviceCustomQueryModel.setSet_companyId(companyId);
        if (gasUser_1 != null) {
            collectDeviceCustomQueryModel.setSet_gasUserId(gasUser_1.getId());
            collectDeviceCustomQueryModel.setSet_gasUserCode(gasUser_1.getCode());
            collectDeviceCustomQueryModel.setSet_gasUserName(gasUser_1.getName());
            collectDeviceCustomQueryModel.setSet_gasUserAddress(gasUser_1.getAddress());
        }
        collectDeviceCustomQueryModel.setSet_updateUserId(loginUserId);
        collectDeviceCustomQueryModel.setSet_updateTime(new Date());
        collectDeviceDao.updateProps(collectDeviceCustomQueryModel);
        //更新DTU
        IotDeviceCustomQueryModel iotDeviceCustomQueryModel = new IotDeviceCustomQueryModel();
        iotDeviceCustomQueryModel.setEqual_id(dtu_1.getId());
        iotDeviceCustomQueryModel.setSet_code(dtuCode);
        iotDeviceCustomQueryModel.setSet_des(body.getDtuDes());
        iotDeviceCustomQueryModel.setSet_typeId(body.getDtuTypeId());
        iotDeviceCustomQueryModel.setSet_simNo(body.getDtuSimNo());
        iotDeviceCustomQueryModel.setSet_simTypeCode(body.getDtuSimTypeCode());
        iotDeviceCustomQueryModel.setSet_iotPlatformDeviceId(dtuCode);
        iotDeviceCustomQueryModel.setSet_updateUserId(loginUserId);
        iotDeviceCustomQueryModel.setSet_updateTime(new Date());
        iotDeviceDao.updateProps(iotDeviceCustomQueryModel);

        /* 返回信息 */
        String transactionId = getTransactionId(header);
        FlowMeterPutResponseModel response = new FlowMeterPutResponseModel();
        response.setTransactionId(transactionId);
        return response;
    }

    //region javadoc注释 : delete
    /**
     * 删除流量计 <br/><br/>
     * 简介 : 物联网设备公司现场实施人员删除流量计和所属的DTU <br/>
     * 步骤 : <br/>
     * 1. 查询流量计：根据流量计编号查询“流量计_1”，如“流量计_1”不存在，抛出异常“流量计不存在”; (√) <br/>
     * 2. 查询DTU：根据“流量计_1”的DTU编号查询“DTU_1”，如果“DTU_1”不存在，抛出异常“DTU不存在”; (√) <br/>
     * 3. 删除流量计：删除“流量计_1”; (√) <br/>
     * 4. 删除DTU：删除“DTU_1”; (√) <br/>
     * @param header <br/>
     * _token : <br/>&nbsp&nbsp&nbsp&nbsp 说明 : 令牌;<br/>&nbsp&nbsp&nbsp&nbsp 是否必填 : true;<br/>&nbsp&nbsp&nbsp&nbsp 数据类型 : string;<br/>
     * _hzhr-user-id : <br/>&nbsp&nbsp&nbsp&nbsp 说明 : 用户编号;<br/>&nbsp&nbsp&nbsp&nbsp 是否必填 : true;<br/>&nbsp&nbsp&nbsp&nbsp 数据类型 : int;<br/>
     * _hzhr-user-code : <br/>&nbsp&nbsp&nbsp&nbsp 说明 : 用户代码;<br/>&nbsp&nbsp&nbsp&nbsp 是否必填 : true;<br/>&nbsp&nbsp&nbsp&nbsp 数据类型 : string;<br/>
     * _hzhr-user-name : <br/>&nbsp&nbsp&nbsp&nbsp 说明 : 用户名;<br/>&nbsp&nbsp&nbsp&nbsp 是否必填 : true;<br/>&nbsp&nbsp&nbsp&nbsp 数据类型 : string;<br/>
     * _hzhr-company-id : <br/>&nbsp&nbsp&nbsp&nbsp 说明 : 公司编号;<br/>&nbsp&nbsp&nbsp&nbsp 是否必填 : true;<br/>&nbsp&nbsp&nbsp&nbsp 数据类型 : int;<br/>
     * _hzhr-dept-id : <br/>&nbsp&nbsp&nbsp&nbsp 说明 : 部门编号;<br/>&nbsp&nbsp&nbsp&nbsp 是否必填 : true;<br/>&nbsp&nbsp&nbsp&nbsp 数据类型 : int;<br/>
     * _hzhr-user-type : <br/>&nbsp&nbsp&nbsp&nbsp 说明 : 用户类型(关联: common_service.options.code, typeCode = 'USER_TYPE');<br/>&nbsp&nbsp&nbsp&nbsp 是否必填 : true;<br/>&nbsp&nbsp&nbsp&nbsp 数据类型 : string;<br/>
     * _hzhr-transaction-id : <br/>&nbsp&nbsp&nbsp&nbsp 说明 : 交易流水号;<br/>&nbsp&nbsp&nbsp&nbsp 是否必填 : true;<br/>&nbsp&nbsp&nbsp&nbsp 数据类型 : string;<br/>
     * _hzhr-transaction-type : <br/>&nbsp&nbsp&nbsp&nbsp 说明 : 交易类型;<br/>&nbsp&nbsp&nbsp&nbsp 是否必填 : true;<br/>&nbsp&nbsp&nbsp&nbsp 数据类型 : string;<br/>
     * _hzhr-access-mode : <br/>&nbsp&nbsp&nbsp&nbsp 说明 : 访问模式 0:一般 1:全局;<br/>&nbsp&nbsp&nbsp&nbsp 是否必填 : false;<br/>&nbsp&nbsp&nbsp&nbsp 默认值 : 0;<br/>&nbsp&nbsp&nbsp&nbsp 数据类型 : int;<br/><br/>
     * @param query <br/><br/>
     * @param body <br/><br/>
     * @throws ServiceException <br/>
     * @see FlowMeterDeleteModel body <br/>
     * @see FlowMeterDeleteResponseModel result <br/>
     */ 
    //endregion
    //region 说明 : delete
    //删除流量计
    //简介 : 物联网设备公司现场实施人员删除流量计和所属的DTU
    //步骤 :
    //1. 查询流量计：根据流量计编号查询“流量计_1”，如“流量计_1”不存在，抛出异常“流量计不存在”; (√)
    //2. 查询DTU：根据“流量计_1”的DTU编号查询“DTU_1”，如果“DTU_1”不存在，抛出异常“DTU不存在”; (√)
    //3. 删除流量计：删除“流量计_1”; (√)
    //4. 删除DTU：删除“DTU_1”; (√)
    //endregion
    //region 参数 : delete
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "令牌",required = true, dataType = "string", paramType = "header"),
    })
    @ApiImplicitInternalParams({
            @ApiImplicitParam(name = "_token", value = "令牌",required = true, dataType = "string", paramType = "header"),
            @ApiImplicitParam(name = "_hzhr-user-id", value = "用户编号",required = true, dataType = "int", paramType = "header"),
            @ApiImplicitParam(name = "_hzhr-user-code", value = "用户代码",required = true, dataType = "string", paramType = "header"),
            @ApiImplicitParam(name = "_hzhr-user-name", value = "用户名",required = true, dataType = "string", paramType = "header"),
            @ApiImplicitParam(name = "_hzhr-company-id", value = "公司编号",required = true, dataType = "int", paramType = "header"),
            @ApiImplicitParam(name = "_hzhr-dept-id", value = "部门编号",required = true, dataType = "int", paramType = "header"),
            @ApiImplicitParam(name = "_hzhr-user-type", value = "用户类型(关联: common_service.options.code, typeCode = 'USER_TYPE')",required = true, dataType = "string", paramType = "header"),
            @ApiImplicitParam(name = "_hzhr-transaction-id", value = "交易流水号",required = true, dataType = "string", paramType = "header"),
            @ApiImplicitParam(name = "_hzhr-transaction-type", value = "交易类型",required = true, dataType = "string", paramType = "header"),
            @ApiImplicitParam(name = "_hzhr-access-mode", value = "访问模式 0:一般 1:全局",defaultValue = "0", required = false, dataType = "int", paramType = "header"),
    })
    //endregion
    //region 请求 : delete
    @RequestMapping(value = "/flow-meters", method = RequestMethod.DELETE)
    //endregion
    @Transactional(rollbackFor = Exception.class)
    public FlowMeterDeleteResponseModel delete(Map<String, String> header, Map<String, Object> query,
                                            FlowMeterDeleteModel body) throws ServiceException {
        /* 查询流量计 */
        String flowMeterCategoryCode = deviceOptions.getCode(DeviceOptionsTypeName.COLLECT_DEVICE_CATEGORY, DeviceOptionsName.COLLECT_DEVICE_CATEGORY.FLOW_METER);
        Integer flowMeterId = body.getFlowMeterId();
        CollectDeviceCustomQueryModel collectDeviceCustomQueryModel = new CollectDeviceCustomQueryModel();
        collectDeviceCustomQueryModel.setEqual_id(flowMeterId);
        collectDeviceCustomQueryModel.setEqual_isValid(CommonOptions.YES_NO.YES);
        collectDeviceCustomQueryModel.setEqual_categoryCode(flowMeterCategoryCode);
        collectDeviceCustomQueryModel.setShow(true);
        CollectDeviceEntity flowMeter_1 = collectDeviceDao.selectEntity(collectDeviceCustomQueryModel);
        if (flowMeter_1 == null) {
            throw new ServiceException(Device_ErrorsEnum.COLLECTDEVICESERVICE_IMPL_DEL_FLOW_METER_201);
        }

        /* 查询DTU */
        String dtuCategoryCode = deviceOptions.getCode(DeviceOptionsTypeName.IOT_DEVICE_CATEGORY, DeviceOptionsName.IOT_DEVICE_CATEGORY.DTU);
        Integer dtuId_1 = flowMeter_1.getIotDeviceId();
        IotDeviceCustomQueryModel iotDeviceCustomQueryModel = new IotDeviceCustomQueryModel();
        iotDeviceCustomQueryModel.setEqual_id(dtuId_1);
        iotDeviceCustomQueryModel.setEqual_isValid(CommonOptions.YES_NO.YES);
        iotDeviceCustomQueryModel.setEqual_categoryCode(dtuCategoryCode);
        IotDeviceEntity dtu_1 = iotDeviceDao.selectEntity(iotDeviceCustomQueryModel);
        if (dtu_1 == null) {
            throw new ServiceException(Device_ErrorsEnum.COLLECTDEVICESERVICE_IMPL_DEL_FLOW_METER_202);
        }

        /* 删除流量计 */
        collectDeviceCustomQueryModel = new CollectDeviceCustomQueryModel();
        collectDeviceCustomQueryModel.setEqual_id(flowMeter_1.getId());
        collectDeviceCustomQueryModel.setSet_isValid(CommonOptions.YES_NO.NO);
        collectDeviceCustomQueryModel.setSet_updateTime(new Date());
        collectDeviceDao.updateProps(collectDeviceCustomQueryModel);

        /* 删除DTU */
        iotDeviceCustomQueryModel = new IotDeviceCustomQueryModel();
        iotDeviceCustomQueryModel.setEqual_id(dtu_1.getId());
        iotDeviceCustomQueryModel.setSet_isValid(CommonOptions.YES_NO.NO);
        iotDeviceCustomQueryModel.setSet_updateTime(new Date());
        iotDeviceDao.updateProps(iotDeviceCustomQueryModel);

        String transactionId = getTransactionId(header);
        FlowMeterDeleteResponseModel response = new FlowMeterDeleteResponseModel();
        response.setTransactionId(transactionId);
        return response;
    }

}

